/**
 * @file main.cpp
 * @brief 演示如何使用 Go 风格的通道与 goroutine。
 *
 * 编译：
 *     g++ -std=c++17 -pthread main.cpp -o csp_demo
 *
 * 运行：
 *     ./csp_demo
 */

#include "go/channel.h"
#include "go/runtime.h"

#include <iostream>
#include <string>
#include <thread>
#include <vector>

using namespace std::chrono_literals;

int main() {
    // 创建一个带缓冲的 channel，容量为 2。
    auto ch = go::make_chan<std::string>(2);

    // 生产者逻辑：模拟大量发送。
    auto producer = [ch](int id, int count) {
        for (int i = 0; i < count; ++i) {
            std::string msg = "生产者 " + std::to_string(id) + " -> 数据 " + std::to_string(i);
            if (!ch->send(msg)) {
                std::cout << "[生产者 " << id << "] 通道已关闭，停止发送\n";
                return;
            }
            std::cout << "[生产者 " << id << "] 发送: " << msg << '\n';
            std::this_thread::sleep_for(40ms);
        }
        std::cout << "[生产者 " << id << "] 完成发送任务\n";
    };

    // 消费者逻辑：持续接收直到通道关闭。
    auto consumer = [ch](int id) {
        std::string msg;
        while (ch->recv(msg)) {
            std::cout << "    [消费者 " << id << "] 收到: " << msg << '\n';
            std::this_thread::sleep_for(120ms); // 模拟处理耗时
        }
        std::cout << "    [消费者 " << id << "] 通道关闭，退出循环\n";
    };

    // 启动 goroutine（实为 std::thread）。
    std::vector<std::thread> workers;
    workers.emplace_back(go::go(producer, 1, 5));
    workers.emplace_back(go::go(producer, 2, 4));
    workers.emplace_back(go::go(consumer, 1));
    workers.emplace_back(go::go(consumer, 2));

    // 主线程等待一段时间，随后关闭通道。
    std::this_thread::sleep_for(1s);
    std::cout << "[main] 调用 close(ch)\n";
    ch->close();

    // 等待所有 goroutine 结束。
    for (auto& t : workers) {
        if (t.joinable()) {
            t.join();
        }
    }

    std::cout << "[main] 程序结束\n";
    return 0;
}